---
slug: react-router-dom@6 #路径，不能重复
title: react-router-dom@6 # 标题
authors: [] # 作者，在authors.yml配置
tags: [facebook, hello, docusaurus] # 标签，在tags.yml配置
toc_min_heading_level: 2 # 最小展示标题
toc_max_heading_level: 5 # 最大展示标题
---


### 安装

```shell
npm install react-router-dom
```

### 变更

#### 移除了

* Switch

* Redirect ----> 代替方案：Navigate

* WithRouter ---> 还记得是干什么的吗？

> react-router-dom@v5给类组件写的一个高阶组件


### 使用

#### `Routes`

> 所有路由组件都必须包裹在`Routes`里面,默认就是匹配到第一个就停止匹配,每一个都是精准匹配

```jsx
import React from 'react';
import {Routes} from 'react-router-dom';
export const First = function () {
    return (
        <>
            <>
                <Routes>
                </Routes>
            </>
        </>
    )

};
```

#### `Route`组件

> 路由匹配,不再基于`component`/`render`,而是`element`,需要写成组件的形式

```jsx

import React from 'react';
import {Routes,Route} from 'react-router-dom';
export const First = function () {
    return (
        <>
            <>
                <Routes>
                    <Route path="/a" element={<A/>}></Route>
                </Routes>
            </>
        </>
    )

};

```

##### `path=*`代表上面的地址一个都不匹配时走这个`Route`

```jsx
import React from 'react';
import {Routes,Route,Navigate} from 'react-router-dom';
export const First = function () {
    return (
        <>
            <>
                <Routes>
                    <Route path="/a" element={<A/>}></Route>
                    <Route path="*" element={<C/>}></Route>
                </Routes>
            </>
        </>
    )

};

```


#### `Navigate`组件

> 遇到`Navigate`组件就跳转

`<Route path="/" element={<Navigate to={'/a'}/>}></Route>`

这句话意思是在根路径`/`时跳转到`/a`地址,甚至可以这样写

```jsx
const isJump = true;
return (
    <>
        {
            isJump ? <Navigate to={'/dashboard'}/> : null
        }
    </>
)
```
> 这样`isJump`如果是true则就跳转到`/dashboard`地址
---


##### replace

> Navigate组件默认是push跳转(新加一条历史记录),加上`replace={true}`即是替换当前历史记录


###### `Navigate`组件甚至能传参

```jsx

<Navigate to={{
    pathname:'/a',
    search:'?id=3'
}}/>

```

### 嵌套路由

> react-router-dom-v6要求所有的路由都写在`<Routes></Routes>`里面，即一个文件里面

```jsx title="src/App.jsx"
import React from 'react';
import {Routes,Route,Navigate} from 'react-router-dom';
export const First = function () {
    return (
        <>
            <>
                <Routes>
                    <Route path="/" element={<Navigate to={'/a'}/>}></Route>
                    <Route path="/a" element={<A/>}>
                        <Route path={'/a/a1'} element={<A1/>}></Route>
                        <Route path={'/a/a2'} element={<A2/>}></Route>
                        <Route path={'/a/a3'} element={<A3/>}></Route>
                    </Route>
                </Routes>
            </>
        </>
    )

};
```

#### 对于父路由如何渲染嵌套路由

> 既然路由都被归到了一个文件了，那A组件如何渲染嵌套的路由呢？？？

**答案是`<Outlet/>`标签，它会渲染对应的嵌套路由**

```jsx title="src/views/A.jsx"
import {NavLink} from 'react-router-dom';
const A = function () {
    return (
        <>
            A component
            <div>
                <NavLink to={'/a/a1'}>goto a1</NavLink>
            </div>
            <div>
                <NavLink to={'/a/a2'}>goto a2</NavLink>
            </div>
            <div>
                <NavLink to={'/a/a3'}>goto a3</NavLink>
            </div>
            <div>
                <Outlet />
            </div>
        </>
    )

};

export default  A;

```

#### `Outlet` 渲染二级或多级路由


### 路由跳转

#### react-router-dom v6版本中实现路由跳转的方式

* `<Link to={'/a'}/>`/`<NavLink to={'/a'}/>` link传参

* `<Navigate to={'/a'}/>` 遇到`Navigate`就会跳转

* `useNavigate()` hooks


```jsx
import {useNavigate} from 'react-router-dom';
const A2 = ()=>{
     const navigate = useNavigate();
     return (
         <>
             a2 component
             <button onClick={()=>{
                 navigate({
                    pathname:'/b',
                    search:'?id=2&name=3'
                 },{replace:true});
             }}>
                 goto b
             </button>
         </>
     )
 }
```


#### 组件获取参数

##### qs库获取

```jsx
import {useLocation} from 'react-router-dom';
import  qs from 'qs';
 const B = function () {
     const location = useLocation();

    return (
        <>
            B component
            <br/>
            <h3>=================></h3>
            <ul>
                {
                    Object.entries(qs.parse(location.search.substring(1))).map(entry => {
                        return (
                            <>
                                <li>{entry[0]}-{entry[1]}</li>
                            </>
                        )
                    })
                }
            </ul>

        </>
    )

};

```

##### `useSearchParams` 获取

```jsx
import {useSearchParams} from 'react-router-dom';
const B = function () {
     const [searchParams] = useSearchParams();
    return (
        <>
                <li>
                    {searchParams.get('id')}- {searchParams.get('name')}
                </li>
        </>
    )

};

```

#### 路径传参

##### 路由文件修改

> 这样c地址的传递参数有一个id和name，但是因为有问号所以id和name可有可无

**因此最后的c地址是:`http://localhost:3000/#/c/100/zs`**

```jsx
<Routes>
<Route path="/c/:id?/:name?" element={<C/>}></Route>
</Routes>

```

##### 传递组件

```jsx
const navigate = useNavigate();
<button onClick={()=>{
                navigate('/c/100/zs')
            }}>go to c </button>
```


##### 接收组件需要使用`useParams`hook

```jsx
const params = useParams();
    console.log(params)
    return (
        <>
            C component
            <ul>
                {
                    Object.entries(params).map(entry => {
                        return (
                            <ol>
                                {entry[0]}-{entry[1]}
                            </ol>
                        )
                    })
                }
            </ul>
        </>
    )

```


#### 隐式传参

**v6中隐式传参信息被保留下来了，但是v5不会保留**

> 隐式传参与v5的history传递方式不同，注意看大括号有两个，因为navigate需要两个参数，state(真正要传的数据)是写在第二个参数的

##### 传参组件

```jsx title="传参组件"
const A1 = ()=>{
     const navigate = useNavigate();
     return (
         <>
             <button onClick={()=>{
                 navigate({
                     pathname:'/d'
                 },{
                     state:{
                         id:100001,
                         name:'李四'
                     }
                 })
             }}>
                 a1 将会使用隐式传参到D组件
             </button>
         </>
     )
 }
```
##### 接收参数组件
> `useLocation()`hooks返回的`location.state`即可

```jsx title="接收组件"
const D = function (){
    const location = useLocation();
    console.log(location);
    return (
        <>
            <ul>
                {
                    Object.entries(location.state).map(entry => {
                        return (
                            <li>
                                {entry[0]}-{entry[1]}
                            </li>
                        )
                    })
                }
            </ul>
        </>
    )
}

```

## 路由表



